package com.vcc.service.impl;

import com.mybatisflex.core.query.QueryChain;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.vcc.data.entity.ClientPermission;
import com.vcc.data.mapper.ClientPermissionMapper;
import com.vcc.service.service.ClientPermissionService;
import org.springframework.stereotype.Service;

import java.util.Collection;
import java.util.List;

import static com.vcc.data.entity.table.ClientPermissionTableDef.CLIENT_PERMISSION;
import static com.vcc.data.entity.table.ClientRolePermissionTableDef.CLIENT_ROLE_PERMISSION;
import static com.vcc.data.entity.table.RoleTableDef.ROLE;
import static com.vcc.data.entity.table.UserRoleTableDef.USER_ROLE;

@Service
public class ClientPermissionServiceImpl extends ServiceImpl<ClientPermissionMapper, ClientPermission> implements ClientPermissionService {
    @Override
    public List<String> listByUserId(Long userId) {
        QueryChain<ClientPermission> queriedChain = queryChain();
        queriedChain.select(CLIENT_PERMISSION.CODE);
        queriedChain.leftJoin(CLIENT_ROLE_PERMISSION.as("crp")).on(CLIENT_ROLE_PERMISSION.PERMISSION_ID.eq(CLIENT_PERMISSION.ID));
        queriedChain.leftJoin(ROLE.as("r")).on(CLIENT_ROLE_PERMISSION.ROLE_ID.eq(ROLE.ID));
        queriedChain.leftJoin(USER_ROLE.as("ur")).on(ROLE.ID.eq(USER_ROLE.ROLE_ID));
        queriedChain.where(USER_ROLE.USER_ID.eq(userId));
        return listAs(queriedChain, String.class);
    }

    @Override
    public List<ClientPermission> listByRoleId(Long roleId) {
        return list(query()
                .select(CLIENT_PERMISSION.ALL_COLUMNS)
                .innerJoin(CLIENT_ROLE_PERMISSION).on(CLIENT_ROLE_PERMISSION.PERMISSION_ID.eq(CLIENT_PERMISSION.ID))
                .where(CLIENT_ROLE_PERMISSION.ROLE_ID.eq(roleId)));
    }

    @Override
    public Boolean existsByCode(String code) {
        return exists(CLIENT_PERMISSION.CODE.eq(code));
    }

    @Override
    public Boolean existsByName(String name) {
        return exists(CLIENT_PERMISSION.NAME.eq(name));
    }

    @Override
    public List<ClientPermission> listByParentId(Long parentId) {
        return list(query()
                .select(CLIENT_PERMISSION.ALL_COLUMNS)
                .where(CLIENT_PERMISSION.PARENT_ID.eq(parentId).or(CLIENT_PERMISSION.ID.eq(parentId))));
    }

    @Override
    public List<Long> listIdsByParentId(Long id) {
        return listAs(query().select(CLIENT_PERMISSION.ID)
                .where(CLIENT_PERMISSION.PARENT_ID.eq(id).or(CLIENT_PERMISSION.ID.eq(id))), Long.class);
    }

    @Override
    public Boolean setParentIdByCodes(List<String> codes, Long parentId) {
        return updateChain()
                .set(CLIENT_PERMISSION.PARENT_ID, parentId)
                .set(CLIENT_PERMISSION.HAS_PARENT, false)
                .where(CLIENT_PERMISSION.CODE.in(codes))
                .update();
    }

    @Override
    public Boolean updateHasCheckedId(Long id, Boolean hasChecked) {
        return updateChain()
                .set(CLIENT_PERMISSION.HAS_CLIENT_CHECKED, hasChecked)
                .where(CLIENT_PERMISSION.ID.eq(id))
                .update();
    }

    @Override
    public Boolean updateHasCheckedIdByParentId(Long parentId, Boolean hasChecked) {
        return updateChain()
                .set(CLIENT_PERMISSION.HAS_CLIENT_CHECKED, hasChecked)
                .where(CLIENT_PERMISSION.ID.eq(parentId).or(CLIENT_PERMISSION.PARENT_ID.eq(parentId)))
                .update();
    }

    @Override
    public Boolean updateHasCheckedId(Collection<Long> ids, Boolean hasChecked) {
        return updateChain()
                .set(CLIENT_PERMISSION.HAS_CLIENT_CHECKED, hasChecked)
                .where(CLIENT_PERMISSION.ID.in(ids))
                .update();
    }
}
